<template>
  <div class="editor-container">
    <div class="main-content-area">
      <div class="button-and-preview-container">
        <div class="button-container">
          <button @click="reloadCaddyfile">重载</button>
          <!-- <button @click="viewLogs">日志</button> -->
          <button @click="startCaddy">启动</button>
          <button @click="stopCaddy">停止</button>
        </div>
        <div class="caddyfile-preview-area">
          <h2>Caddyfile 内容预览</h2>
          <pre ref="editorRef" v-if="content" contenteditable="true" @dblclick="isEditing = true" @blur="logContentAndSave"><code class="hljs" v-html="content"></code></pre>
          <p v-else>加载中...</p>
        </div>
      </div>
      <div v-if="logMessages.length > 0" class="logs-container">
        <h3>实时日志</h3>
        <pre id="log-container" class="log-output">{{ logMessages.join('\n') }}</pre>
      </div>
    </div>
  </div>
</template>

<script setup>
import { ref, onMounted } from 'vue'
import hljs from 'highlight.js/lib/core'
import caddyfile from 'highlight.js/lib/languages/nginx'

hljs.registerLanguage('caddyfile', caddyfile)

const content = ref(null)
const editorRef = ref(null)
const isEditing = ref(false)


const saveContent = async (newContent) => {
  try {
    // 检查内容是否为空
    if (newContent === undefined || newContent === null) {
      console.error('Cannot save undefined or null content')
      return
    }
    
    // 从HTML内容中提取纯文本
    let plainText = newContent
    // 如果内容包含HTML标签,尝试提取纯文本
if (typeof newContent === 'string' && newContent.includes('<')) {
  // 先将<br>标签替换为特殊标记
  const markedContent = newContent.replace(/<br\s*\/?>/gi, '###NEWLINE###');
  const tempDiv = document.createElement('div');
  tempDiv.innerHTML = markedContent;
  // 提取文本后再将特殊标记转回换行符
  plainText = (tempDiv.textContent || tempDiv.innerText || newContent)
    .replace(/###NEWLINE###/g, '\n');
}
    console.log('Saving content:', plainText)
    const response = await fetch('/api/caddyfile/edit', {
      method: 'POST',
      headers: {
        'Content-Type': 'text/plain'
      },
      body: plainText
    })
    if (!response.ok) {
      throw new Error('Failed to save content')
    }
    console.log('Content saved successfully')
  } catch (error) {
    console.error('Error saving content:', error)
  }
}

// 创建一个带超时的 fetch 函数
async function fetchWithTimeout(url, options, timeout = 5000) {
  const controller = new AbortController()
  const id = setTimeout(() => controller.abort(), timeout)
  try {
    const response = await fetch(url, { ...options, signal: controller.signal })
    clearTimeout(id)
    return response
  } catch (err) {
    if (err.name === 'AbortError') {
      console.error('请求超时:', url)
      content.value = '请求超时，请检查服务器是否运行'
    } else {
      console.error('请求失败:', err)
      content.value = '请求失败: ' + err.message
    }
    return null
  }
}

async function reloadCaddyfile() {
  console.log('重载Caddyfile');
  try {
    const response = await fetch('/api/caddy/reload', {
      method: 'POST',
    });
    const result = await response.json();
    if (result.success) {
      alert('Caddy 配置已成功重载');
      console.log('Caddy reloaded successfully:', result.message);
    } else {
      alert('Caddy 重载失败: ' + result.message);
      console.error('Failed to reload Caddy:', result.message);
    }
  } catch (error) {
    alert('重载请求失败: ' + error.message);
    console.error('Error reloading Caddy:', error);
  }
}

async function startCaddy() {
  console.log('启动Caddy');
  try {
    const response = await fetch('/api/caddy/start', {
      method: 'POST',
    });
    const result = await response.json();
    if (result.success) {
      alert('Caddy 已成功启动');
      console.log('Caddy started successfully:', result.message);
    } else {
      alert('Caddy 启动失败: ' + result.message);
      console.error('Failed to start Caddy:', result.message);
    }
  } catch (error) {
    alert('启动请求失败: ' + error.message);
    console.error('Error starting Caddy:', error);
  }
}

async function stopCaddy() {
  console.log('停止Caddy');
  try {
    const response = await fetch('/api/caddy/stop', {
      method: 'POST',
    });
    const result = await response.json();
    if (result.success) {
      alert('Caddy 已成功停止');
      console.log('Caddy stopped successfully:', result.message);
    } else {
      alert('Caddy 停止失败: ' + result.message);
      console.error('Failed to stop Caddy:', result.message);
    }
  } catch (error) {
    alert('停止请求失败: ' + error.message);
    console.error('Error stopping Caddy:', error);
  }
}

const logMessages = ref([])
const logSocket = ref(null)

function viewLogs() {
  console.log('查看日志')
  if (logSocket.value && logSocket.value.readyState === WebSocket.OPEN) {
    logSocket.value.close()
    logSocket.value = null
    logMessages.value = [] // Clear logs when closing
    console.log('WebSocket connection closed')
    return
  }

  const protocol = window.location.protocol === 'https:' ? 'wss:' : 'ws:'
  const host = window.location.host
  logSocket.value = new WebSocket(`${protocol}//${host}/api/logs`)

  logSocket.value.onopen = () => {
    console.log('WebSocket connection established for logs')
    logMessages.value.push('--- 日志流已连接 ---')
  }
    logMessages.value.push('--- 日志流已连接 ---')

  logSocket.value.onmessage = (event) => {
    console.log('Received log message:', event.data);
    logMessages.value.push(event.data);
    // Auto-scroll to the bottom of the log display
    const logContainer = document.getElementById('log-container');
    if (logContainer) {
      logContainer.scrollTop = logContainer.scrollHeight;
    }
  }

  logSocket.value.onerror = (error) => {
    console.error('WebSocket error:', error);
    logMessages.value.push('--- WebSocket 错误 ---');
  }

  logSocket.value.onclose = () => {
    console.log('WebSocket connection closed for logs');
    logMessages.value.push('--- 日志流已断开 ---');
    logSocket.value = null; // Ensure socket is reset
  }
}

import { onUnmounted } from 'vue'

onMounted(async () => {
  // 获取 Caddyfile 内容
  const response = await fetchWithTimeout('/api/caddyfile', {})
  if (!response || !response.ok) {
    return
  }

  const data = await response.text()
  console.log('Fetched Caddyfile content:', data)

  // 高亮显示
  const highlighted = hljs.highlight(data, { language: 'caddyfile' }).value
  content.value = highlighted
})
const logContentAndSave = () => {
  const contentHTML = editorRef.value?.innerHTML;
  if (contentHTML !== undefined && contentHTML !== null) {
    saveContent(contentHTML)
  } else {
    console.log('No content to save: contentHTML is undefined or null')
  }
}

onUnmounted(() => {
  if (logSocket.value && logSocket.value.readyState === WebSocket.OPEN) {
    logSocket.value.close()
  }
})
</script>

<style scoped>
.editor-container {
  display: flex;
  flex-direction: row;
  gap: 20px;
  padding: 20px;
  text-align: left;
}

.button-and-preview-container {
  display: flex;
  flex-direction: column;
  gap: 10px;
  flex: 1;
}

.logs-container {
  flex: 0 0 40%;
  min-width: 0;
  border: 1px solid #4a5568;
  padding: 10px;
  border-radius: 4px;
  display: flex;
  flex-direction: column;
}

.main-content-area {
  display: flex;
  gap: 20px;
}

.caddyfile-preview-area {
  flex: 1;
  min-width: 0;
}

.button-container {
  display: flex;
  gap: 10px;
}

h2 {
  margin-bottom: 10px;
}

.monaco-editor-container {
  width: 100%;
  height: 400px;
  border: 1px solid #4a5568;
  border-radius: 4px;
  margin-bottom: 10px;
}

button {
  background-color: #2d3748;
  color: #e2e8f0;
  border: 1px solid #4a5568;
}

button:hover {
  background-color: #4a5568;
}

.logs-container h3 {
  margin-bottom: 10px;
}

.log-output {
  background-color: #1a202c;
  color: #e2e8f0;
  padding: 10px;
  flex-grow: 1;
  overflow-y: auto;
  white-space: pre-wrap;
  word-break: break-all;
  border-radius: 4px;
  font-family: 'Courier New', Courier, monospace;
  min-height: 300px;
}

button:active {
  background-color: #1a202c;
}
</style>